package edu.bu.CS893.data;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.security.MessageDigest;
import android.xml.parsers.SAXParserFactoryImpl;

public class FacebookApiFetcher {
	private static String FB_REST_URL = "http://api.facebook.com/restserver.php";

	public static FacebookData doRequest(Map<String, String> theParameters) {
		String aRequestUrl = FB_REST_URL + "?" + toQueryString(theParameters, false);

		FacebookData aData;
		try {
			URL aUrl = new URL(aRequestUrl);

			SAXParserFactory aSaxFactory = SAXParserFactoryImpl.newInstance();
			SAXParser aSaxParser = aSaxFactory.newSAXParser();
			XMLReader aXmlReader = aSaxParser.getXMLReader();
			ContentHandler aFacebookResponseHandler = new FacebookResponseHandler();
			aXmlReader.setContentHandler(aFacebookResponseHandler);
			aXmlReader.parse(new InputSource(aUrl.openStream()));

			// after parsed, get record
			aData = ((FacebookResponseHandler) aFacebookResponseHandler).getFacebookData();
		} catch (Exception e) {
			return null;
		}

		return aData;
	}

	public static String getSignature(Map<String, String> theParameters,
			String theSecret) {
		String aQueryString = toQueryString(theParameters, true) + theSecret;

		MessageDigest aMd5Digester;
		try {
			aMd5Digester = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException nsae) {
			// we're boned
			return null;
		}
		byte aSignatureBytes[] = aMd5Digester.digest(aQueryString.getBytes());

		StringBuffer aDigestedString = new StringBuffer();
		for (byte aByte : aSignatureBytes)
			aDigestedString.append(String.format("%02x", 0xFF & aByte));

		return aDigestedString.toString();
	}

	/**
	 * returns elements in an alphabetically ordered query string
	 */
	private static String toQueryString(
			java.util.Map<String, String> theParameters, boolean isForSignature) {

		SortedSet<String> aSortedSet = new TreeSet<String>();
		aSortedSet.addAll(theParameters.keySet());

		StringBuilder aStringBuilder = new StringBuilder();
		for (String aKey : aSortedSet) {
			String aValue = null;
			try {
				aValue = isForSignature ? theParameters.get(aKey) : URLEncoder
						.encode(theParameters.get(aKey), "UTF-8");
			} catch (UnsupportedEncodingException e) {
			}

			if (!isForSignature && aStringBuilder.length() > 0)
				aStringBuilder.append("&");

			aStringBuilder.append(aKey + "=" + aValue);
		}

		return aStringBuilder.toString();
	}

}
